package com.cloudkinto.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.cloudkinto.bo.order.makeshop.MakeShopShopConfig;
import org.mountcloud.graphql.GraphqlClient;
import org.mountcloud.graphql.request.mutation.DefaultGraphqlMutation;
import org.mountcloud.graphql.request.mutation.GraphqlMutation;
import org.mountcloud.graphql.request.param.RequestObjectParameter;
import org.mountcloud.graphql.request.query.DefaultGraphqlQuery;
import org.mountcloud.graphql.request.query.GraphqlQuery;
import org.mountcloud.graphql.request.result.ResultAttributtes;
import org.mountcloud.graphql.response.GraphqlResponse;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;

/**
 * @author long
 * @Description make shop Graphql类型的接口对接
 * @Date 2025/5/6 16:35
 */
public class MakeShopGraphqlUtils {

    /**
     * 构建一个带请求头的Graphql客户端
     *
     * @param config 配置信息
     * @return Graphql客户端
     */
    private static GraphqlClient buildGraphqlClient(MakeShopShopConfig config) {
        //构建一个Graphql客户端
        GraphqlClient graphqlClient = GraphqlClient.buildGraphqlClient(config.getUrl());

        //创建http请求头
        Map<String, String> httpHeaders = new HashMap<>(8);
        httpHeaders.put("content-type", "application/json");
        httpHeaders.put("authorization", config.getToken());
        httpHeaders.put("x-api-key", config.getApiKey());
        httpHeaders.put("x-timestamp", String.valueOf(DateUtil.date().setTimeZone(TimeZone.getTimeZone("GMT+9")).getTime() / 1000));
        //设置http请求的头
        graphqlClient.setHttpHeaders(httpHeaders);
        return graphqlClient;
    }

    /**
     * 发送graphql的【Query】请求
     *
     * @param config            配置信息
     * @param apiName           方法名
     * @param request           请求参数 value 如果为对象需要 {@link RequestObjectParameter} 用这个类构造
     * @param resultClazz       返回类型
     * @param resultAttributtes 需要返回的字段
     * @param <T>               返回类型
     * @return 返回值
     * @throws Exception 异常
     */
    public static <T> T postGraphqlQuery(MakeShopShopConfig config, String apiName, Map<String, Object> request, Class<T> resultClazz, ResultAttributtes... resultAttributtes) throws Exception {

        //构建一个Graphql客户端
        GraphqlClient graphqlClient = buildGraphqlClient(config);

        //构建查询对象 apiName类似restful的接口名称
        GraphqlQuery query = new DefaultGraphqlQuery(apiName);
        //设置接口的请求参数
        if (CollUtil.isNotEmpty(request)) {
            for (Map.Entry<String, Object> entry : request.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof RequestObjectParameter) {
                    query.getRequestParameter().addObjectParameter(key, value);
                } else {
                    query.addParameter(key, value);
                }
            }
        }
        //设置需要查询的参数
        query.addResultAttributes(resultAttributtes);

        //通过上面的信息进行查询
        GraphqlResponse response;
        try {
            response = graphqlClient.doQuery(query);
        } catch (Exception e) {
            throw new Exception("graphql调用失败," + e.getMessage());
        }

        //获取数据，数据为map类型
        Map result = response.getData();
        Object data = result.get("data");
        if (result.containsKey("errors")) {
            throw new Exception("graphql调用失败:" + result.get("errors"));
        }
        if (Objects.isNull(data)) {
            throw new Exception("graphql调用失败:" + response);
        }
        Map dataMap = (Map) data;
        return JSONUtil.toBean(JSONUtil.toJsonStr(dataMap.get(apiName)), resultClazz);
    }

    /**
     * 发送graphql的【Mutation】请求
     */
    public static <T> T postGraphqlMutation(MakeShopShopConfig config, String apiName, Map<String, Object> request, Class<T> resultClazz, ResultAttributtes... resultAttributtes) throws Exception {

        //构建一个Graphql客户端
        GraphqlClient graphqlClient = buildGraphqlClient(config);
        //创建mutation  apiName类似restful的接口名称
        GraphqlMutation mutation = new DefaultGraphqlMutation(apiName);
        //设置接口的请求参数
        if (CollUtil.isNotEmpty(request)) {
            for (Map.Entry<String, Object> entry : request.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof RequestObjectParameter) {
                    mutation.getRequestParameter().addObjectParameter(key, value);
                } else {
                    mutation.addParameter(key, value);
                }
            }
        }
        //设置需要查询的参数
        mutation.addResultAttributes(resultAttributtes);

        //通过上面的信息进行修改
        GraphqlResponse response;
        try {
            response = graphqlClient.doMutation(mutation);
        } catch (IOException e) {
            throw new Exception("graphql调用失败," + e.getMessage());
        }
        //获取数据，数据为map类型
        Map result = response.getData();
        Object data = result.get("data");
        if (result.containsKey("errors")) {
            throw new Exception("graphql调用失败:" + result.get("errors"));
        }
        if (Objects.isNull(data)) {
            throw new Exception("graphql调用失败:" + response);
        }
        Map dataMap = (Map) data;
        return JSONUtil.toBean(JSONUtil.toJsonStr(dataMap.get(apiName)), resultClazz);
    }
}